package com.cn.onetrip.view;

import io.vov.utils.Log;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.cn.onetrip.activity.R;
import com.cn.onetrip.objects.RouteObj;
import com.cn.onetrip.objects.RoutePointObj;
import com.cn.onetrip.untility.NetworkManager;
import com.cn.onetrip.untility.SyncBitmapLoader;
import com.cn.onetrip.untility.SyncBitmapLoader.OnImageLoadListener;
import com.cn.onetrip.untility.SysApplication;

public class CustomMapView extends RelativeLayout {

	private final int GREY_MAP = 0;
	private final int MAP_ROUTE = 1;
	private final int COLOR_MAP = 2;

	public static final int MAP_LOAD_SUCCESS = 3;
	public static final int MAP_LOAD_FAIL = 4;
	public static final int MAP_QUALITY_LOW = 5;

	private final int CHARGE_MESSAGE = 9;

	private Context context;

	private RelativeLayout layoutMap;
	private MapImageView imageMap;
	private ImageView popViewBG;
	private ImageView imageRouteLine;

	private PopupLayout layoutPopup;

	private SyncBitmapLoader syncBitmapLoader = null;
	private boolean isquit = false;

	private RoutePointObj popPointObj = null;
	private Point ptPopStart = new Point();

	private RouteObj routeObj = null;

	private boolean isMapMove = false;
	private boolean isClickMarker = false;
	private boolean isAnimationStart = false;
	private boolean isShowRoute = true;
	private boolean isInit = true;
	private boolean isInMapPage = true;

	private int viewWidth = 0;
	private int viewHeight = 0;
	private int mouseDownX = 0;
	private int mouseDownY = 0;

	private Handler parentHandler = null;

	private int routeNum = 0;

	public CustomMapView(Context context) {
		super(context);
		this.context = context;
	}

	public CustomMapView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();

		// init popup view
		// layoutPopup = (PopupLayout)findViewById(R.id.popup_view);
		layoutMap = (RelativeLayout) findViewById(R.id.layout_map);
		imageMap = (MapImageView) findViewById(R.id.image_map);
		popViewBG = (ImageView) findViewById(R.id.image_pop_bg);
		imageRouteLine = (ImageView) findViewById(R.id.image_route_line);

		layoutPopup = (PopupLayout) View.inflate(context, R.layout.popup_view,
				null);

		if (imageMap != null) {

			if (routeObj != null)
				initData();

			imageMap.setOnTouchListener(new OnTouchListener() {

				@Override
				public boolean onTouch(View v, MotionEvent event) {

					if (isAnimationStart)
						return false;

					switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN: {
						Log.i("ACTION_DOWN");
						mouseDownX = (int) event.getX();
						mouseDownY = (int) event.getY();
					}
						break;

					case MotionEvent.ACTION_MOVE: {
						if (Math.abs(event.getX() - mouseDownX) > 10
								|| Math.abs(event.getY() - mouseDownY) > 10) {
							isMapMove = true;
							Log.i("ACTION_MOVE");
						}
					}
						break;

					case MotionEvent.ACTION_UP: {
						if (!isMapMove) {
							if (popPointObj != null)
								layoutPopup.disappearAnimation();

							// popPointObj = null;
							imageMap.invalidate();
						}

						isMapMove = false;
						isClickMarker = false;
					}

						break;

					default:
						break;
					}

					return false;
				}
			});
		}
	}

	public boolean isShowRoute() {
		return isShowRoute;
	}

	public void setShowRoute(boolean isShowRoute) {
		this.isShowRoute = isShowRoute;
	}

	public void loadMap() {
		if (isShowRoute)
			loadMap(SysApplication.contentObj.guide_grey_icon, GREY_MAP);
		else
			loadMap(SysApplication.contentObj.guide_color_icon, COLOR_MAP);
	}

	public void setData(RouteObj routeObj, Handler handler,
			boolean isInMapPage, int viewWidth, int viewHeight) {
		this.routeObj = routeObj;
		this.parentHandler = handler;
		this.viewWidth = viewWidth;
		this.viewHeight = viewHeight;
		this.isInMapPage = isInMapPage;

		if (imageMap != null) {
			initData();
		}
	}

	public void configurationChanged() {
		int temp = viewWidth;
		viewWidth = viewHeight;
		viewHeight = temp;

		// if (popPointObj != null)
		// layoutPopup.disappearAnimation();
		//
		// popPointObj = null;
		// isClickMarker = false;

		imageMap.configurationChanged();
	}

	private void initData() {
		if (SysApplication.bmpGrey == null) {
			loadMap(SysApplication.contentObj.guide_grey_icon, GREY_MAP);
		} else {
			initGreyMap();
			// if (SysApplication.bmpRoute == null)
			loadMap(routeObj.routeUrl, MAP_ROUTE);
			// else
			// initRoute();

			Message message = new Message();
			message.what = MAP_LOAD_SUCCESS;
			parentHandler.sendMessage(message);
			checkMapQuality();
		}
	}

	public void setScreenLock() {
		layoutPopup.LockScreen();
	}

	public Handler mhandler = new Handler() {

		public void dispatchMessage(android.os.Message msg) {

			if (msg.what == 0) {
				refreshIfMapMove();
			} else if (msg.what == PopupLayout.DIS_ANIM_END) {

				popViewBG.setVisibility(View.GONE);
				if (isClickMarker) {
					popupOverlay();
				} else {
					layoutMap.removeView(layoutPopup);
					popPointObj = null;
					showAllPops();
				}

				isAnimationStart = false;

			} else if (msg.what == PopupLayout.POP_ANIM_END) {
				isAnimationStart = false;
				imageMap.invalidate();
			}
		};
	};

	private void loadMap(String mapUrl, final int mapType) {
		if (syncBitmapLoader == null) {
			syncBitmapLoader = new SyncBitmapLoader(context);
		}

		syncBitmapLoader.loadBitmap(mapUrl, new OnImageLoadListener() {

			@Override
			public void onError() {
				syncBitmapLoader.threadQuit();
				sendMapLoadMsg(false);
			}

			@Override
			public void onBitmapLoad(Bitmap bitmap) {
				if (bitmap != null) {
					Message msg = new Message();
					msg.what = mapType;
					msg.obj = bitmap;

					mapLoadHandler.sendMessage(msg);
					if (isInit)
						loadMap(routeObj.routeUrl, MAP_ROUTE);

				} else {
					syncBitmapLoader.threadQuit();
					sendMapLoadMsg(false);
				}
			}

			@Override
			public void onGetBitmapWH(int width, int height) {

				if (isInit) {
					SysApplication.bmpWidth = width;
					SysApplication.bmpHeight = height;
				}

			}
		});
	}

	public Handler mapLoadHandler = new Handler() {

		public void dispatchMessage(android.os.Message msg) {

			Bitmap bmp = (Bitmap) msg.obj;
			if (msg.what == GREY_MAP) {
				SysApplication.recycleBmpColor();
				SysApplication.bmpGrey = bmp;

				if (isInit) {
					initGreyMap();
				} else {
					// imageMap.setBitmap(SysApplication.bmpGrey);
					imageMap.setBackgroundDrawable(new BitmapDrawable(
							SysApplication.bmpGrey));
					layoutMap.setVisibility(View.VISIBLE);
					repositionPoints();
					resetRouteLine();
					sendMapLoadMsg(true);
				}
			} else if (msg.what == MAP_ROUTE) {
				SysApplication.bmpRoute = bmp;
				initRoute();
				sendMapLoadMsg(true);

			} else if (msg.what == COLOR_MAP) {
				SysApplication.recycleBmpGrey();
				layoutMap.setVisibility(View.GONE);
				SysApplication.bmpColor = bmp;
				// imageMap.setBitmap(SysApplication.bmpColor);
				imageMap.setBackgroundDrawable(new BitmapDrawable(
						SysApplication.bmpColor));
				sendMapLoadMsg(true);
			}

			checkMapQuality();
		};
	};

	private void sendMapLoadMsg(boolean isSuccess) {
		Message message = new Message();
		message.what = isSuccess ? MAP_LOAD_SUCCESS : MAP_LOAD_FAIL;
		parentHandler.sendMessage(message);
	}

	private void initGreyMap() {

		imageMap.InitMapView(SysApplication.bmpGrey, mhandler, isInMapPage);
		addPoints(); // add scenic point
		isInit = false;

		layoutPopup.setHandler(mhandler);
	}

	private void initRoute() {
		imageRouteLine.setBackgroundDrawable(new BitmapDrawable(
				SysApplication.bmpRoute));
		resetRouteLine();
	}

	private void checkMapQuality() {
		if ((isShowRoute && SysApplication.bmpGrey == null)
				|| (!isShowRoute && SysApplication.bmpColor == null))
			return;

		if ((isShowRoute && SysApplication.bmpGrey.getWidth() < SysApplication.bmpWidth)
				|| (!isShowRoute && SysApplication.bmpColor.getWidth() < SysApplication.bmpWidth)) {
			Message message = new Message();
			message.what = MAP_QUALITY_LOW;
			parentHandler.sendMessage(message);
		}
	}

	private void refreshIfMapMove() {

		if (layoutPopup != null && popPointObj != null
				&& layoutPopup.getVisibility() == View.VISIBLE) {

			Point ptPop = calculatePointPos(popPointObj.ptPos);
			ptPop.y = ptPop.y
					- getResources().getDrawable(R.drawable.pop1)
							.getIntrinsicHeight() / 5; // offset height

			Point ptPopup = new Point(ptPop);
			ptPopup.x += viewWidth / 2;
			ptPopup.y += viewHeight / 2;

			RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
					viewWidth * 2, viewHeight * 2);
			lp.setMargins(-viewWidth / 2 + (ptPopup.x - ptPopStart.x),
					-viewHeight / 2 + (ptPopup.y - ptPopStart.y), -viewWidth
							/ 2 - (ptPopup.x - ptPopStart.x), -viewHeight / 2
							- (ptPopup.y - ptPopStart.y));
			layoutPopup.setLayoutParams(lp);

			View v = ((Activity) context).getWindow().findViewById(
					Window.ID_ANDROID_CONTENT);

			if (ptPop.x <= 0 || ptPop.x >= v.getWidth() || ptPop.y <= 0
					|| ptPop.y >= v.getHeight()) {
				isClickMarker = false;
				layoutPopup.disappearAnimation();

			} else {
				// >= SDK level 11
				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
					layoutPopup.repositionPopup(ptPopup);
			}

		}

		if (isShowRoute) {
			repositionPoints();
			resetRouteLine();
		}

		imageMap.invalidate();
	}

	public void resetRouteLine() {
		Point ptMap = imageMap.getXYPoint();

		RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
				(int) imageMap.getMapWidth(), (int) imageMap.getMapHeight());

		lp.setMargins(ptMap.x, ptMap.y, -((int) imageMap.getMapWidth()
				- viewWidth + ptMap.x), -((int) imageMap.getMapHeight()
				- viewHeight + ptMap.y));
		imageRouteLine.setLayoutParams(lp);
	}

	public void onDestroy() {
		SysApplication.recycleBmps();
		imageRouteLine.setBackgroundDrawable(null);
		imageMap.setBackgroundDrawable(null);
		if (layoutPopup != null)
			layoutPopup.ClearSubItem();
	}

	public void clearAudio() {
		if (layoutPopup != null)
			layoutPopup.ClearSubItem();
	}

	public void addPoints() {
		if (layoutMap.getChildCount() > 0) {
			layoutMap.removeViews(2, layoutMap.getChildCount() - 2);
		}
		for (int i = routeObj.pointList.size() - 1; i >= 0; i--) {
			final RoutePointObj pointData = routeObj.pointList.get(i);

			pointData.marker = new ImageButton(context);
			int drawableID = 0;
			if (pointData.typeID == RoutePointObj.TYPE_IN_LINE) {
				drawableID = getResources().getIdentifier("pop" + (i + 1),
						"drawable", context.getPackageName());
			} else {
				drawableID = getResources().getIdentifier(
						"other_pop" + (i + 1), "drawable",
						context.getPackageName());
			}

			pointData.marker.setBackgroundResource(drawableID);

			layoutMap.addView(pointData.marker);

			Point pt = calculatePointPos(pointData.ptPos);
			pointData.marker.setLayoutParams(getPointLP(pt));

			pointData.marker.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					if (SysApplication.contentObj.isFree == false
							&& pointData.index != 0 && pointData.index != 1) {
						NetworkManager.ChargeMessage(context);
						return;
					}
					if (popPointObj != null) {
						return;
					}
					isClickMarker = true;

					// if (popPointObj != null) {
					// layoutPopup.disappearAnimation();
					// popPointObj = pointData;
					// } else {
					if (popPointObj == null) {
						popPointObj = pointData;
						popupOverlay();
					}

					hideOtherPops();
					imageMap.invalidate();
				}
			});
		}
	}

	private void repositionPoints() {
		for (int i = 0; i < routeObj.pointList.size(); i++) {
			RoutePointObj pointData = routeObj.pointList.get(i);
			Point pt = calculatePointPos(pointData.ptPos);
			pointData.marker.setLayoutParams(getPointLP(pt));
		}
	}

	private LayoutParams getPointLP(Point pt) {
		RelativeLayout.LayoutParams lp = null;
		Drawable drawable = getResources().getDrawable(R.drawable.pop1);
		int width = drawable.getIntrinsicWidth();
		int height = drawable.getIntrinsicHeight();

		if (isInMapPage) {
			lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
					LayoutParams.WRAP_CONTENT);
		} else {

			width = width * 3 / 4;
			height = height * 3 / 4;
			lp = new RelativeLayout.LayoutParams(width, height);
		}

		int left = pt.x - width / 2;
		int top = pt.y - height;
		int right = viewWidth - pt.x - width;
		int bottom = viewHeight - pt.y;
		lp.setMargins(left, top, right, bottom);

		return lp;
	}

	private Point calculatePointPos(Point pt) {

		// Drawable drawable = getResources().getDrawable(R.drawable.pop1);
		int pointX = pt.x + 34;// drawable.getIntrinsicWidth() / 2;
		int pointY = pt.y + 102;// drawable.getIntrinsicHeight();

		Point ptPoint = new Point();

		Point ptMap = imageMap.getXYPoint();

		ptPoint.x = (int) ((float) pointX * imageMap.getMapWidth()
				/ SysApplication.bmpWidth + ptMap.x);
		ptPoint.y = (int) ((float) pointY * imageMap.getMapHeight()
				/ SysApplication.bmpHeight + ptMap.y);

		return ptPoint;
	}

	private void popupOverlay() {

		isAnimationStart = true;
		popViewBG.setVisibility(View.VISIBLE);

		ptPopStart = calculatePointPos(popPointObj.ptPos);
		ptPopStart.x += viewWidth / 2;
		ptPopStart.y += viewHeight / 2;

		ptPopStart.y = ptPopStart.y
				- getResources().getDrawable(R.drawable.pop1)
						.getIntrinsicHeight() / 5;

		// RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
		// viewWidth, viewHeight);
		// lp.setMargins(0, 0, 0, 0);
		RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
				viewWidth * 2, viewHeight * 2);
		lp.setMargins(-viewWidth / 2, -viewHeight / 2, -viewWidth / 2,
				-viewHeight / 2);
		layoutPopup.setLayoutParams(lp);

		layoutPopup.setVisibility(View.VISIBLE);
		layoutMap.removeView(popPointObj.marker);
		layoutMap.addView(layoutPopup);
		layoutMap.addView(popPointObj.marker);

		layoutPopup.setPoint(popPointObj, ptPopStart);
		layoutPopup.popupAnimation();
	}

	private void hideOtherPops() {
		for (int i = 0; i < routeObj.pointList.size(); i++) {
			RoutePointObj pointData = routeObj.pointList.get(i);
			if (pointData.index != popPointObj.index) {
				int drawableID = 0;
				if (pointData.typeID == RoutePointObj.TYPE_IN_LINE) {
					drawableID = getResources().getIdentifier(
							"pop_down_" + (i + 1), "drawable",
							context.getPackageName());
				} else {
					drawableID = getResources().getIdentifier(
							"other_pop_down" + (i + 1), "drawable",
							context.getPackageName());
				}

				if (pointData.marker != null) {
					pointData.marker.setBackgroundResource(drawableID);
					pointData.marker.setClickable(false);
				}
			}
		}
	}

	public void showAllPops() {
		for (int i = 0; i < routeObj.pointList.size(); i++) {
			RoutePointObj pointData = routeObj.pointList.get(i);
			// pointData.marker.setVisibility(View.VISIBLE);
			int drawableID = 0;
			if (pointData.typeID == RoutePointObj.TYPE_IN_LINE) {
				drawableID = getResources().getIdentifier("pop" + (i + 1),
						"drawable", context.getPackageName());
			} else {
				drawableID = getResources().getIdentifier(
						"other_pop" + (i + 1), "drawable",
						context.getPackageName());
			}

			if (pointData.marker != null) {
				pointData.marker.setBackgroundResource(drawableID);
				pointData.marker.setClickable(true);
			}
		}
	}

	public void hidePopup() {
		if (layoutPopup.getVisibility() == View.VISIBLE) {
			popPointObj = null;
			layoutPopup.ClearSubItem();
			layoutMap.removeView(layoutPopup);
			popViewBG.setVisibility(View.GONE);
		}
	}
}
